package com.shermanzhou.springbootflowable.demo.flow2;

import lombok.Builder;
import lombok.Data;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhouchaoqun02
 * @date 2020-07-11 15:56
 */
@Data
@Builder
public class EngineApprovalFlow {
    private String flowId;
    private String startNodeId;
    // 节点-后续节点映射。key: nodeId, value: nextNodeIds,节点的后续节点的nodeId列表
    private Map<String, Set<String>> outGoingsMap;
    // 节点ID-节点对象映射，仅限当前流程，不包含子流程节点。key: nodeId, value: 节点对象实例
    private Map<String, EngineApprovalFlowNode2> nodeMap;
    // 节点-子流程映射。 key: nodeId, value: subFlowIds,节点的子流程实例的flowId（支持多实例子流程）
    private Map<String, List<String>> subFlowsMap;

    public void addNode(EngineApprovalFlowNode2 node) {
        if (nodeMap == null) {
            nodeMap = new LinkedHashMap<>();
        }
        nodeMap.put(node.getNodeId(), node);
    }


    public void addOutGoing(String fromNodeId, String toNodeId) {
        if (outGoingsMap == null) {
            outGoingsMap = new LinkedHashMap<>();
        }
        Set<String> nextNodeIds = outGoingsMap.computeIfAbsent(fromNodeId, k -> new HashSet<>());
        nextNodeIds.add(toNodeId);
    }

    public void addOutGoings(String fromNodeId, Set<String> toNodeIds) {
        if (outGoingsMap == null) {
            outGoingsMap = new LinkedHashMap<>();
        }
        outGoingsMap.put(fromNodeId, toNodeIds);
    }

    public Set<String> getNextNodeIds(String fromNodeId) {
        if (outGoingsMap == null) {
            return Collections.emptySet();
        }
        Set<String> nextNodeIds = outGoingsMap.get(fromNodeId);
        if (nextNodeIds == null) {
            return Collections.emptySet();
        }
        return nextNodeIds;
    }

    public List<EngineApprovalFlowNode2> getNextNodes(String fromNodeId) {
        if (outGoingsMap == null) {
            return Collections.emptyList();
        }
        Set<String> nextNodeIds = outGoingsMap.get(fromNodeId);
        if (nextNodeIds == null) {
            return Collections.emptyList();
        }
        return nextNodeIds.stream().map(nodeId -> nodeMap.get(nodeId)).collect(Collectors.toList());
    }

}
